package com.laysonx.data.police.core;

import com.laysonx.data.police.annotation.EnableDataVerify;
import com.laysonx.data.police.constant.Constant;
import com.laysonx.data.police.handler.DataHandler;
import com.laysonx.data.police.handler.DisposeHandler;
import com.laysonx.data.police.handler.VerifyHandler;
import com.laysonx.data.police.support.DefaultBean;
import com.laysonx.data.police.util.DataVerifyUtil;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInvocation;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 数据检查
 *
 * @author: Laysonx
 * @date: 2019/9/27 10:58
 */
@Getter
@Setter
@Slf4j
public class DataVerifyInfoChecker {

    /**
     * 存放验证对象 以及其 验证方式
     */
    private Map<Class<?>, Map<String, VerifyHandler>> verifyHelper;

    /**
     * 存放验证对象 以及其 清洗方式
     */
    private Map<Class<?>, Map<String, DataHandler>> dataHelper;

    /**
     * 存放验证对象 以及其 验证后处理方式
     */
    private Map<Class<?>, Map<String, DisposeHandler>> disposeHelper;

    public Object around(MethodInvocation invocation) throws Throwable {
        Object result = invocation.proceed();
        Object waitVerifyData = result;
        if (DataVerifyUtil.shouldVerify()) {
            if (waitVerifyData != null) {
                // 获取数据验证注解
                EnableDataVerify enableDataVerify = DataVerifyUtil.getVerifyTarget();
                // 获取注解传递的 验证所需的接口类型
                Class<?>[] value = enableDataVerify.value();
                String tag = enableDataVerify.tag();
                // 返回数据的结构不同，根据情况处理返回数据
                if (dataHelper != null && dataHelper.size() > 0) {
                    for (Map.Entry<Class<?>, Map<String, DataHandler>> specialClassEntry : dataHelper.entrySet()) {
                        Class<?> specialClass = specialClassEntry.getKey();
                        if (specialClass.isInstance(waitVerifyData)) {
                            Map<String, DataHandler> tagMap = dataHelper.get(specialClass);
                            DataHandler dataHandler = tagMap.get(tag);
                            if (dataHandler != null) {
                                waitVerifyData = dataHandler.getResult(waitVerifyData);
                            }
                        }
                    }
                }

                // 检查数据
                if (value != null && value.length > 0) {
                    for (Class<?> waitVerifyClass : value) {
                        // 处理集合
                        if (waitVerifyData instanceof List) {
                            Collection dataCollection = (Collection) waitVerifyData;
                            for (Object data : dataCollection) {
                                this.verifyData(data, waitVerifyClass, invocation, enableDataVerify);
                            }
                        } else {
                            this.verifyData(waitVerifyData, waitVerifyClass, invocation, enableDataVerify);
                        }
                    }
                }
            }
        }
        return result;
    }

    /**
     * 验证数据
     *
     * @param waitVerifyData
     * @param waitVerifyClass
     * @param invocation
     * @param enableDataVerify
     * @author: Laysonx
     * @date: 2019/10/22 15:42
     * @return: void
     */
    private void verifyData(Object waitVerifyData, Class<?> waitVerifyClass, MethodInvocation invocation, EnableDataVerify enableDataVerify) {
        String tag = enableDataVerify.tag();
        if (waitVerifyClass.isInstance(waitVerifyData)) {
            Map<String, VerifyHandler> tagMap = verifyHelper.get(waitVerifyClass);
            if (tagMap == null || tagMap.size() == 0) {
                log.warn("验证[{}]时未找到与之匹配的VerifyHandler", waitVerifyClass);
                return;
            }
            VerifyHandler verifyHandler = tagMap.get(tag);
            if (verifyHandler == null) {
                log.warn("验证[{}]时，标签[{}]下的未找到与之匹配的VerifyHandler", waitVerifyClass, tag);
                return;
            }
            boolean verifyResult = verifyHandler.verify(waitVerifyClass.cast(waitVerifyData));
            // 获取默认验证后处理方式
            Map<String, DisposeHandler> tagDisposeMap = disposeHelper.get(DefaultBean.class);
            DisposeHandler disposeHandler = tagDisposeMap.get(Constant.DEFAULT_TAG);
            if (disposeHelper.containsKey(waitVerifyClass)) {
                tagDisposeMap = disposeHelper.get(waitVerifyClass);
                DisposeHandler tagDisposeHandler = tagDisposeMap.get(tag);
                if (tagDisposeHandler != null) {
                    disposeHandler = tagDisposeHandler;
                }
            }
            // 验证完成后处理结果
            disposeHandler.dispose(verifyResult, invocation, enableDataVerify);
        }
    }
}
